--#include "RankDef.lua" once
--脚本的排行榜统一用ID,因为通过ID可以去拿到默认值

-----------------------------------------------只有一个nPoint的排行榜----------------------------------------------------
--初始化排行榜
function gRankMgr_Init(nRankId, numMax)
	if(type(nRankId) ~= 'number' or type(numMax) ~= 'number')then
		return print(actorId, nRankId)
	end
	local rankName = RankList[nRankId].strName	
	local ranking = Ranking.getRanking( rankName )
	if(ranking ~= nil)then
		return false
	end
	ranking = Ranking.add( rankName, numMax, 1, 10 )
	if(ranking == nil)then
		return false
	end
	if not Ranking.load(ranking, nil) then
		Ranking.addColumn(ranking, "name")
	end
	Ranking.addRef( ranking )
	return true
end

--获取排行榜数据
function gRankMgr_GetValue(actorId, nRankId)
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number')then
		return print(actorId, nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if ranking then
		local item = Ranking.getItemPtrFromId( ranking, actorId)
		if item then	--已经榜上有名
			return Ranking.getPoint(item)
		end
	end
	return 0
end

--设置排行榜数据
function gRankMgr_SetRank(actorId, nRankId, newValue,  rankInfo)  --当sub 0不为actorname的时候需要使用
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number' or type(newValue) ~= 'number')then
		return print(actorId, nRankId ,addValue)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return
	end
	local item = Ranking.getItemPtrFromId( ranking, actorId)
	if item then			--已经榜上有名
		Ranking.setItem(ranking, actorId, newValue)
		return true
	end	
	local setValue
	if rankInfo then
		setValue = rankInfo
	else
		local pActor = System.getEntityPtrByActorID(actorId)	
		if(pActor == nil)then	-- 如果没记录,玩家又没在线,不处理	
			return false
		end	
		setValue = Actor.getName(pActor)
	end
	item = Ranking.addItem(ranking, actorId, newValue)
	if item then
		Ranking.setSub(item, 0, setValue)
	end	
end

--增加排行榜数据
function gRankMgr_AddValue(actorId, nRankId, addValue, rankInfo)--当sub 0不为actorname的时候需要使用
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number' or type(addValue) ~= 'number')then
		return print(actorId, nRankId ,addValue)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return
	end
	local item = Ranking.getItemPtrFromId( ranking, actorId)
	if item then	--已经榜上有名
		Ranking.updateItem(ranking, actorId, addValue)
		return true
	end			--新加的
	local setValue
	if rankInfo then
		setValue = rankInfo
	else
		local pActor = System.getEntityPtrByActorID(actorId)	
		if(pActor == nil)then	-- 如果没记录,玩家又没在线,不处理	
			return false
		end	
		setValue = Actor.getName(pActor)
	end
	item = Ranking.addItem(ranking, actorId, addValue)
	if item then
		Ranking.setSub(item, 0, setValue)
	end	
	return true
end

--移除排行榜数据
function gRankMgr_RemoveItemById(actorId, nRankId)
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number')then
		return print(actorId, nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return
	end
	Ranking.removeId(ranking, actorId)
end

--发送排行榜前num名
function gRankMgr_SendToClient(sysarg, nRankId, num, rankLimit, systemId, msgId)
	if(type(nRankId) ~= 'number' or type(num) ~= 'number' or type(systemId) ~= 'number' or type(msgId) ~= 'number')then
		return print(actorId, nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return
	end
	local itemNum = Ranking.getRankItemCount(ranking)
	if num < Ranking.getRankItemCount(ranking) then
		itemNum = num
	end
	local pack = DataPack.allocPacket(sysarg, systemId, msgId)
	if (pack == nil) then
		return
	end
	DataPack.writeByte(pack, itemNum)
	for idx=1,itemNum do
		local rankItem = Ranking.getItemFromIndex(ranking, idx-1)
		if rankItem then
			local playerId  = Ranking.getId(rankItem)
			local value 	= Ranking.getPoint(rankItem)
			local name 	 	= Ranking.getSub(rankItem, 0)
			DataPack.writeUInt(pack, playerId)
			DataPack.writeUInt(pack, value)
			DataPack.writeString(pack, name)
		end
	end
	--我的数据
	local myId = Actor.getActorId(sysarg)
	local myStar 	= 0
	local myIdx 	= 0
	local item = Ranking.getItemPtrFromId( ranking, myId)
	if item then
		myStar = Ranking.getPoint(item) or 0
		if myStar < rankLimit then			--未上榜
			myIdx = 0
		else
			myIdx = Ranking.getIndexFromPtr(item) + 1
		end
	end	
	DataPack.writeUInt(pack, myStar)
	DataPack.writeWord(pack, myIdx)
	DataPack.flush(pack)
end

-----------------------------------------------多个value的排行榜----------------------------------------------------

--排行榜初始化函数
--RankName:排行榜的名称
--sRankFile:排行榜保存文件
--tbColumn:排行榜列 表 tbColumn = {"column0","column1","column2",}, {标题, 是否客户端显示}...} 
--nMax:发给客户端最多的行数
function gRankMgr_InitEx(nRankId, tbColumn, nMax)
	if(type(nRankId) ~= 'number' or type(nMax) ~= 'number')then
		return print(nRankId, nMax)
	end
	rankName = RankList[nRankId].strName
	local sRankFile = rankName								--默认排行榜的名字就是文件的名字
	local ranking = Ranking.getRanking(rankName) 			--通过排行名称获取排行对象
	if ranking ~= nil then  					  			--有排行对象则创建失败
		return false
	end
	ranking = Ranking.add(rankName,nMax,0)					--创建排行榜
	if ranking == nil then
		return false
	end
	local isLoad = Ranking.load(ranking,sRankFile)          --读取文件内容
	if isLoad == false then									--加载排行榜失败,进行标题初始化
		for i=1, table.getn(tbColumn) do
			Ranking.addColumn(ranking,tbColumn[i])			--添加列名字  
		end
	else
		local colCount = Ranking.GetRankColumnCount(ranking)--如果排行榜的文件已经存在	
		local srcSize= #tbColumn
		if colCount < srcSize then
			for i = colCount + 1, srcSize do
				Ranking.addColumn(ranking, tbColumn[i]) 	--添加列名字 
			end
		end
	end
	Ranking.addRef(ranking) 								--增加对此排行对象的引用计数
end

--设置排行榜的数据
--colIdx：从1开始，0是name
--在涉及到领取道具的时候，为了避免出现异常，必须判断一下返回值
function gRankMgr_SetRankEx(actorId, nRankId, colIdx, newColValue, rankInfo)--当sub 0不为actorname的时候需要使用
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number')then
		return print(actorId, nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return false
	end
	local item = Ranking.getItemPtrFromId( ranking, actorId )
	if item then	--已经榜上有名
		if rankInfo then
			Ranking.setSub(item, 0, rankInfo)
		end
		Ranking.setSub(item, colIdx, newColValue)   				   --这里不一定能设置成功
		if Ranking.getSub(item, colIdx) ~= tostring(newColValue) then  --列没有设置成功
			print(actorId, nRankId, colIdx, newColValue)
			return false
		end
		return true
	end				--新加的


	local setValue
	if rankInfo then
		setValue = rankInfo
	else
		local pActor = System.getEntityPtrByActorID(actorId)	
		if(pActor == nil)then	-- 如果没记录,玩家又没在线,不处理	
			return false
		end	
		setValue = Actor.getName(pActor)
	end
	

	--item = Ranking.addItem(ranking, actorId, newColValue)		--新加的时候不能用这个值，这等于给积分加上了colIdx的值了
	item = Ranking.addItem(ranking, actorId, 0)
	if (item == nil) then
		return false
	end
	Ranking.setSub(item, 0, setValue)
	Ranking.setSub(item, colIdx, newColValue)
	if Ranking.getSub(item, colIdx) ~= tostring(newColValue) then  --列没有设置成功
		return false
	end		
	return true
end

--增加排行榜数据
function gRankMgr_AddValueEx(actorId, nRankId, colIdx, addValue, rankInfo)--当sub 0不为actorname的时候需要使用
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number' or type(addValue) ~= 'number')then
		return print(actorId, nRankId ,addValue)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return
	end
	local item = Ranking.getItemPtrFromId( ranking, actorId)
	if item then	--已经榜上有名
		local newColValue = tonumber(Ranking.getSub(item, colIdx)) or 0
		newColValue = newColValue + addValue		
		Ranking.setSub(item, colIdx, newColValue)  
		return true
	end			--新加的

	local setValue
	if rankInfo then
		setValue = rankInfo
	else
		local pActor = System.getEntityPtrByActorID(actorId)	
		if(pActor == nil)then	-- 如果没记录,玩家又没在线,不处理	
			return false
		end	
		setValue = Actor.getName(pActor)
	end	
	--item = Ranking.addItem(ranking, actorId, addValue)		--新加的时候不能用这个值，这等于给积分加上了colIdx的值了
	item = Ranking.addItem(ranking, actorId, 0)
	if item then
		Ranking.setSub(item, colIdx, addValue)
		Ranking.setSub(item, 0, setValue)
	end
	return true
end

local function _getValueByItem(item, colIdx, nRankId)
	if (item == nil) then	
		return nil
	end
	if(type(colIdx) ~= 'number' or type(nRankId) ~= 'number')then
		return print(colIdx, nRankId)
	end	
	local colValue = Ranking.getSub(item, colIdx)
	local Default = RankList[nRankId].tabColumn[2][colIdx + 1] --默认值
	if(Default == nil)then
		return nil
	end	
	if colValue == "-" then	--返回默认值
		return Default
	end
	if(type(Default) == 'string') then
		return colValue			
	end
	return tonumber(colValue) 	
end

-- 获取第colIdx列的数据
--如果排行榜不存在，必须返回nil，为无效数据，避免异常情况
function gRankMgr_GetValueById(actorId, nRankId, colIdx)
	if(type(actorId) ~= 'number' or type(nRankId) ~= 'number')then
		return print(actorId, nRankId)
	end	
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return nil
	end
	local item = Ranking.getItemPtrFromId( ranking, actorId )
	return _getValueByItem(item,colIdx,nRankId)
end

--按名次获取第colIdx列的数据(名次从0开始)
function gRankMgr_GetValueByIndx(rankIndx, nRankId, colIdx)
	if(type(rankIndx) ~= 'number' or type(nRankId) ~= 'number')then
		return print(rankIndx, nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if (ranking == nil) then
		return nil
	end
	local item = Ranking.getItemFromIndex( ranking, rankIndx )
	return _getValueByItem(item,colIdx,nRankId)
end

-----------------------------------所有排行榜共用接口-----------------------------------
function gRankMgr_Clear(nRankId)
	if(type(nRankId) ~= 'number')then
		return print(nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if(ranking == nil)then
		return
	end
	Ranking.clearRanking(ranking)
	Ranking.save(ranking, rankName, true)
end

--排行榜销毁函数
function gRankMgr_Remove(nRankId)
	if(type(nRankId) ~= 'number')then
		return print(nRankId)
	end
	local rankName = RankList[nRankId].strName
	Ranking.removeRanking(rankName)
end

function gRankMgr_Save(nRankId)
	if(type(nRankId) ~= 'number')then
		return print(nRankId)
	end
	local rankName = RankList[nRankId].strName
	local ranking = Ranking.getRanking( rankName )
	if ranking then
		Ranking.save(ranking, rankName, true)
	end
end

--所有排行榜统一初始化
function gRankMgr_AutoInit()
	--print(" Enter gRankMgr_AutoInit")
	for RankId,RankInfo in pairs(RankList)do
		local tbColumn = RankInfo.tabColumn[1]
		local nMax = RankInfo.nMaxRecord
		if(0 <#tbColumn)then
			gRankMgr_InitEx(RankId, tbColumn, nMax)
		else
			gRankMgr_Init(RankId, nMax)
		end
	end
end
gRankMgr_AutoInit()



--[[
	-- 使用例子
	local actorId = Actor.getIntProperty( sysarg, PROP_ENTITY_ID )
	local colIdx = 1
	local newColValue = 99
	gRankMgr_SetRankEx(actorId, 2001, colIdx, newColValue)
	newColValue = gRankMgr_GetValueById(actorId, 2001, colIdx)
	print(newColValue)	
	--2001是排行榜的Id,定义在data\functions\Common\RankDef.txt
]]

